<template>
  <transition name="fade" v-if="loading">
    <loading/>
  </transition>
  <el-row v-else style="justify-content: center">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <h1 class="h1">写一篇博客</h1>
      </div>
      <div>
        <el-form :model="form" :rules="rules" ref="form"
                 label-width="100px">
          <el-form-item label="标题" prop="title">
            <el-input v-model="form.title" show-word-limit
                      placeholder="给博客起个好听的名字"
                      maxlength="30"></el-input>
          </el-form-item>
          <el-form-item label="摘要" prop="subheading">
            <el-input v-model="form.subheading" show-word-limit
                      placeholder="一句话简明扼要的概括下主要内容"
                      maxlength="60"></el-input>
          </el-form-item>
          <el-form-item label="分类" prop="categoryId">
            <el-select v-model="form.categoryId"
                       class="select-block"
                       placeholder="请选择分类">
              <el-option v-for="category in categorys" :label="category.name"
                         :value="category.value"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="选择标签" prop="label">
            <el-select
              class="select-block"
              v-model="labels"
              multiple
              filterable
              default-first-option
              placeholder="请选择文章标签">
              <el-option
                v-for="item in options"
                :key="item.value"
                :label="item.name"
                :value="item.name">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="谁可以看到" prop="openness">
            <el-radio-group v-model="form.openness">
              <el-radio :label="0">仅自己</el-radio>
              <el-radio :label="1">所有人</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="博客封面图" prop="coverImage" required>
            <div>
              <!-- 多图片上传 -->
              <el-upload v-if="multiple" action='string'
                         list-type="picture-card" accept="image/*"
                         :on-preview="handlePreview" :auto-upload="false"
                         :on-remove="handleRemove" :http-request="upload"
                         :on-change="consoleFL" :file-list="uploadList">
                <i class="el-icon-plus"></i>
              </el-upload>
              <!-- 单图片上传 -->
              <el-upload v-else class="avatar-uploader" action="'string'"
                         list-type="picture"
                         :auto-upload="false" :show-file-list="false"
                         :on-change="handleCrop" :http-request="upload">
                <img v-if="form.coverImage" :src="form.coverImage"
                     class="avatar"
                     ref="singleImg" @mouseenter="mouseEnter"
                     @mouseleave="mouseLeave"
                     :style="{width:width+'px'}">
                <i v-else class="el-icon-plus avatar-uploader-icon"
                   :style="{width:width+'px',height:height+'px','line-height':height+'px','font-size':height/6+'px'}"></i>
                <!-- 单图片上传状态显示 -->
                <!-- <div v-if="form.coverImage" class="reupload" ref="reupload" @click.stop="handlePreviewSingle" @mouseenter="mouseEnter" @mouseleave="mouseLeave" :style="{width:reuploadWidth+'px',height:reuploadWidth+'px','line-height':reuploadWidth+'px','font-size':reuploadWidth/5+'px'}">重新上传</div> -->
                <div id="uploadIcon" v-if="form.coverImage" ref="reupload"
                     @mouseenter="mouseEnter" @mouseleave="mouseLeave"
                     :style="{width:'100%'}">
                  <i class="el-icon-zoom-in" @click.stop="handlePreviewSingle"
                     :style="{color:'#2E2E2E',fontSize:'25px',display:'inline-block',paddingRight:'15px'}"></i>
                  <i class="el-icon-upload"
                     :style="{color:'#2E2E2E',fontSize:'25px',display:'inline-block'}"></i>
                </div>
                <div class="reupload" ref="uploading"
                     :style="{width:reuploadWidth+'px',height:reuploadWidth+'px','line-height':reuploadWidth+'px','font-size':reuploadWidth/5+'px'}">
                  上传中..
                </div>
                <div class="reupload" ref="failUpload"
                     :style="{width:reuploadWidth+'px',height:reuploadWidth+'px','line-height':reuploadWidth+'px','font-size':reuploadWidth/5+'px'}">
                  上传失败
                </div>
              </el-upload>
              <!-- 多图片预览弹窗 -->
              <el-dialog :visible.sync="dialogVisible">
                <img width="100%" :src="dialogImageUrl" alt="">
              </el-dialog>
              <!-- 剪裁组件弹窗 -->
              <el-dialog :visible.sync="cropperModel" width="1100px"
                         :before-close="beforeClose">
                <Cropper :img-file="file" ref="vueCropper"
                         :fixedNumber="fixedNumber" @upload="upload">
                </Cropper>
              </el-dialog>
            </div>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="submitForm('form')">立即创建
            </el-button>
            <el-button @click="resetForm('form')">重置</el-button>
          </el-form-item>
        </el-form>
      </div>
      <div class="editer">
        <h1>博客内容</h1>
        <codemirror-editor @setMd="setContentMd" @setHtml="setContentHtml"
                           ref="child"/>
      </div>
    </el-card>

  </el-row>
</template>

<script>
import Loading from "../../components/Loading";
import CodemirrorEditor from "./view/CodemirrorEditor";
import Cropper from '../../components/Cropper';
import {toBase64} from "../../assets/scripts/util";
import fileApi from "../../api/file";
import {saveBlog, categorys, labels, getBlog, updateBlog} from "../../api/api";

export default {
  name: "App",
  components: {
    Loading,
    CodemirrorEditor,
    Cropper
  },
  props: {
    targetUrl: {
      // 上传地址
      type: String,
      // default: '/storage/upload'
      default: `${process.env.API_ROOT}/sys/oss/upload`
    },
    multiple: {
      // 多图开关
      type: Boolean,
      default: false
    },
    initUrl: {
      // 初始图片链接
      default: ''
    },
    fixedNumber: {
      // 剪裁框比例设置
      default: function () {
        return [320, 200];
      }
    },
    width: {
      // 单图剪裁框宽度
      type: Number,
      default: 320
    },
    height: {
      // 单图剪裁框高度
      type: Number,
      default: 320
    }
  },
  data() {
    var validateCoverImage = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请上传一张博客封面'));
      } else {
        callback();
      }
    };
    return {
      loading: true,
      form: {
        id: '',
        title: '',
        subheading: '',
        categoryId: '',
        openness: 0,
        label: '',
        contentMd: '',
        contentHtml: '',
        coverImage: '',
      },
      labels: [],
      categorys: [{
        name: '奇淫技巧',
        value: 1,
      }],
      file: '', // 当前被选择的图片文件
      imageUrl: '', // 单图情况框内图片链接
      dialogImageUrl: '', // 多图情况弹窗内图片链接
      uploadList: [], // 上传图片列表
      reupload: true, // 控制"重新上传"开关
      dialogVisible: false, // 展示弹窗开关
      cropperModel: false, // 剪裁组件弹窗开关
      reuploadWidth: this.height * 0.7, // 动态改变”重新上传“大小
      options: [{
        value: 'HTML',
        name: 'HTML'
      }, {
        value: 'CSS',
        name: 'CSS'
      }, {
        value: 'JavaScript',
        name: 'JavaScript'
      }],
      rules: {
        title: [
          {required: true, message: '请输入博客名称', trigger: 'blur'},
          {min: 1, max: 30, message: '长度在 1 到 30 个字符', trigger: 'blur'}
        ],
        subheading: [
          {required: true, message: '请输入摘要', trigger: 'blur'},
          {min: 1, max: 60, message: '长度在 1 到 60 个字符', trigger: 'blur'}
        ],
        categoryId: [
          {required: true, message: '请选择分类', trigger: 'change'}
        ],
        label: [
          {required: true, message: '请设置标签', trigger: 'change'}
        ],
        openness: [
          {required: true, message: '请选择活动资源', trigger: 'change'}
        ],
        coverImage: [
          {validator: validateCoverImage, trigger: 'change'}
        ]
      }
    };
  },
  updated() {
    if (this.$refs.vueCropper) {
      this.$refs.vueCropper.Update();
    }
  },
  watch: {
    initUrl: function (val) {
      // 监听传入初始化图片
      // console.info('watch');
      if (val) {
        if (typeof this.initUrl === 'string') {
          this.form.coverImage = val;
        } else {
          this.uploadList = this.formatImgArr(val);
          // this.$emit('imgupload', this.uploadList);
        }
      }
    },
    labels: function (newLabel, oldLabel) {
      this.form.label = newLabel.join(',');
    }
  },
  mounted() {
    setTimeout(() => {
      this.loading = false;
    }, 100);
    if (typeof this.initUrl === 'string') {
      this.form.coverImage = this.initUrl;
    } else {
      this.uploadList = this.formatImgArr(this.initUrl);
    }
  },
  created() {
    var query = this.$route.query;
    let id = query.id;
    if (id !== undefined) {
      getBlog(id).then(response => {
        const {data, state, message} = response
        if (state !== 200) {
          this.$message.error(message)
        }
        // this.form = data;
        this.form.id = data.id;
        this.form.title = data.title;
        this.form.subheading = data.subheading;
        this.form.categoryId = data.categoryId;
        this.form.coverImage = data.coverImage;
        if (data.openness === 'ALL') {
          this.form.openness = 1;
        } else if (data.openness === 'SELF_ONLY'){
          this.form.openness = 0;
        }
        this.form.label = data.label;
        this.form.contentMd = data.contentMd;
        this.labels = data.label.split(',');
        let that = this;
        let md = data.contentMd;
        setTimeout(function () {
          that.$refs.child.updateMd(md);
        }, 500);

        // this.$refs.child.updateMd(data.contentMd);
      }).catch(error => {
        this.$message.error(error)
      });
    }
    categorys().then(response => {
      const {data, state, message} = response
      if (state !== 200) {
        this.$message.error(message)
      }
      this.categorys = data.map((v) => {
        return {
          value: Number(v.id),
          name: v.name
        }
      })
    }).catch(error => {
      this.$message.error(error)
    });
    labels().then(response => {
      const {data, state, message} = response
      if (state !== 200) {
        this.$message.error(message)
      }
      this.options = data.map((v) => {
        return {
          value: v.id,
          name: v.name
        }
      })
    }).catch(error => {
      this.$message.error(error)
    });
  },
  methods: {
    setContentMd(data) {
      this.form.contentMd = data;
    },
    setContentHtml(data) {
      this.form.contentHtml = data;
    },
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          if (this.form.id === '') {
            saveBlog(this.form).then(response => {
              const {data, state, message} = response
              if (state !== 200) {
                this.$message.error(message);
                const isProd = process.env.NODE_ENV === `production`
                if (isProd) {
                  window.location.href = 'https://blog.zealsay.com/login.html';
                } else {
                  window.location.href = 'http://localhost:8010/login.html';
                }
              }
              //跳转页面
              const isProd = process.env.NODE_ENV === `production`
              if (isProd) {
                window.location.href = 'https://blog.zealsay.com/admin/blog/list.html';
              } else {
                window.location.href = 'http://localhost:8010/admin/blog/list.html';
              }
            }).catch(error => {
              this.$message.error(error)
            });
          } else {
            updateBlog(this.form).then(response => {
              const {data, state, message} = response
              if (state !== 200) {
                this.$message.error(message);
                const isProd = process.env.NODE_ENV === `production`
                if (isProd) {
                  window.location.href = 'https://blog.zealsay.com/login.html';
                } else {
                  window.location.href = 'http://localhost:8010/login.html';
                }
              }
              //跳转页面
              const isProd = process.env.NODE_ENV === `production`
              if (isProd) {
                window.location.href = 'https://blog.zealsay.com/admin/blog/list.html';
              } else {
                window.location.href = 'http://localhost:8010/admin/blog/list.html';
              }
            }).catch(error => {
              this.$message.error(error)
            });
          }

        } else {
          return false;
        }
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    },
    /** **************************** multiple多图情况 **************************************/
    handlePreview(file) {
      // 点击进行图片展示
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    handleRemove(file, fileList) {
      // 删除图片后更新图片文件列表并通知父级变化
      this.uploadList = fileList;
      this.$emit('imgupload', this.uploadList);
      // this.$emit('imgupload', this.formatImgArr(this.uploadList));
    },
    consoleFL(file, fileList) {
      // 弹出剪裁框，将当前文件设置为文件
      this.cropperModel = true;
      this.file = file;
      // this.uploadList = fileList;
    },
    /************************************************************************************/

    /** **************************** single单图情况 **************************************/
    handlePreviewSingle(file) { // 点击进行图片展示
      this.dialogImageUrl = this.file.url;
      this.dialogVisible = true;
    },
    mouseEnter() { // 鼠标划入显示“重新上传”
      this.$refs.reupload.style.display = 'block';
      if (this.$refs.failUpload.style.display === 'block') {
        this.$refs.failUpload.style.display = 'none';
      }
      this.$refs.singleImg.style.opacity = '0.6';
    },
    mouseLeave() {
      // 鼠标划出隐藏“重新上传”
      this.$refs.reupload.style.display = 'none';
      this.$refs.singleImg.style.opacity = '1';
    },
    handleCrop(file, files) {
      // console.log(file);
      // 点击弹出剪裁框
      this.cropperModel = true;
      this.file = file;
      // this.form.coverImage = file.url
    },
    /************************************************************************************/

    async upload(data) {
      // 自定义upload事件
      if (!this.multiple) {
        // 如果单图，则显示正在上传
        this.$refs.uploading.style.display = 'block';
      }
      let img = new Image();
      img.src = data;
      img.onload = async () => {
        // let _data = this.compress(img);
        let blob = this.dataURItoBlob(data);
        let files = new window.File([blob], this.file.name, {type: this.file.type})
        let formData = new FormData();
        formData.append('file', blob, this.file.name); // 有的后台需要传文件名，不然会报错
        // this.imgUpload(formData);
        this.myUploadImage(files)
      };
    },
    async imgUpload(formData) {
      const res = await this.$http({
        url: 'sys/oss/upload',
        method: 'post',
        data: formData,
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      });
      if (!this.multiple) {
        // 上传完成后隐藏正在上传
        this.$refs.uploading.style.display = 'none';
      }
      if (res.data.code === 0) {
        // 上传成功将照片传回父组件
        const currentPic = res.data.url;
        if (this.multiple) {
          this.uploadList.push({
            url: currentPic,
            uid: '111'
          });
          this.$emit('imgupload', this.uploadList);// 根据自己实际项目需要将照片返回给父组件
          // this.uploadList.pop();
          // this.$emit('imgupload', this.formatImgArr(this.uploadList));
        } else {
          this.$emit('imgupload', currentPic);
        }
        this.$refs.vueCropper.isDisabled = false;
      } else {
        // 上传失败则显示上传失败，如多图则从图片列表删除图片
        if (!this.multiple) {
          this.$refs.failUpload.style.display = 'block';
        } else {
          this.uploadList.pop();
        }
        this.$refs.vueCropper.isDisabled = false;
      }
      this.cropperModel = false;
    },
    formatImgArr(arr) {
      const result = arr.map((item, index) => {
        if (typeof item === 'string') {
          return {
            url: item,
            uid: `index${index}`
          };
        } else {
          return item.url;
        }
      });
      return result;
    },
    beforeClose() {
      // this.uploadList.pop();
      console.log(this.uploadList);
      this.cropperModel = false;
    },
    // 压缩图片
    compress(img) {
      let canvas = document.createElement('canvas');
      let ctx = canvas.getContext('2d');
      // let initSize = img.src.length;
      let width = img.width;
      let height = img.height;
      canvas.width = width;
      canvas.height = height;
      // 铺底色
      ctx.fillStyle = '#fff';
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(img, 0, 0, width, height);
      // 进行压缩
      let ndata = canvas.toDataURL('image/jpeg', 0.8);
      return ndata;
    },
    // base64转成bolb对象
    dataURItoBlob(base64Data) {
      let byteString;
      if (base64Data.split(',')[0].indexOf('base64') >= 0) {
        byteString = atob(base64Data.split(',')[1]);
      } else {
        byteString = unescape(base64Data.split(',')[1]);
      }
      let mimeString = base64Data.split(',')[0].split(':')[1].split(';')[0];
      let ia = new Uint8Array(byteString.length);
      for (let i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
      }
      return new Blob([ia], {type: mimeString});
    },
    myUploadImage(file) {
      toBase64(file)
        .then((base64Content) => {
          fileApi
            .fileUpload(base64Content, file)
            .then((url) => {
              // this.uploaded(url);
              if (!this.multiple) {
                // 上传完成后隐藏正在上传
                this.$refs.uploading.style.display = 'none';
              }
              if (url !== '') {
                // 上传成功将照片传回父组件
                const currentPic = url;
                if (this.multiple) {
                  this.uploadList.push({
                    url: currentPic,
                    uid: '111'
                  });
                } else {
                  this.form.coverImage = url;
                }
                this.$refs.vueCropper.isDisabled = false;
              } else {
                // 上传失败则显示上传失败，如多图则从图片列表删除图片
                if (!this.multiple) {
                  this.$refs.failUpload.style.display = 'block';
                } else {
                  this.uploadList.pop();
                }
                this.$refs.vueCropper.isDisabled = false;
              }
            })
            .catch((err) => {
              this.$message.error(err.message);
            });
        })
        .catch((err) => {
          this.$message.error(err.message);
        });
      this.cropperModel = false;
    },
  }
};
</script>

<style lang="less" scoped>
.fade-enter,
.fade-leave-to {
  opacity: 0;
}

.fade-enter-to,
.fade-leave {
  opacity: 1;
}

.fade-enter-active,
.fade-leave-active {
  transition: all 1s;
}

.select-block {
  display: block;
}

.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}

.avatar-uploader-icon {
  color: #8c939d;
  text-align: center;
}

.avatar {
  display: block;
}

.reupload {
  border-radius: 50%;
  position: absolute;
  color: #fff;
  background-color: #000000;
  opacity: 0.6;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: none;
}

.editer {
  height: 1200px;
}

//#uploadIcon {
//  position: absolute;
//  top: 50%;
//  left: 50%;
//  transform: translate(-50%, -50%);
//  display: none;
//}
</style>
